Skip to content

Commit

Permalink
[PLAY-1566] Multiple User Bubble Size Prop (#3719)
Browse files Browse the repository at this point in the history
**What does this PR do?** A clear and concise description with your
runway ticket url.
Runway https://runway.powerhrg.com/backlog_items/PLAY-1566

Added Size prop for multi user stacked kit's bubble variant

All the deets are [in this
figma](https://www.figma.com/design/Q1mz4nRApKN5rlzqCV4IC0/Multiple-User-Bubble?node-id=3701-1514&t=8SZl8NL1XQV1BelO-0)

I had to manually map out a bunch of sizing and position css, I didn't
use tokens because not all of the sizes matched our tokens.

review env link
https://pr3719.playbook.beta.hq.powerapp.cloud/kits/multiple_users_stacked/react#sizes


![screenshot-127_0_0_1_3000-2024_09_27-11_35_41](https://github.com/user-attachments/assets/ea4da377-4e83-41d7-9f9d-ba24c8d9a4e4)
  • Loading branch information
markdoeswork authored Oct 17, 2024
1 parent dd19284 commit 580161f
Show file tree
Hide file tree
Showing 10 changed files with 686 additions and 88 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,76 @@
@import "../tokens/opacity";
@import "../pb_avatar/avatar";

$sizes: (
"avatar": ("sm": 38px, "md": 60px, "lg": 80px, "xl": 100px),
"first-item-double": ("sm": 20px, "md": 32px, "lg": 44px, "xl": 56px),
"first-item-triple": ("sm": 16px, "md": 24px, "lg": 32px, "xl": 44px),
"first-item-quadruple": ("sm": 16px, "md": 28px, "lg": 36px, "xl": 44px),
"second-item-double": ("sm": 12px, "md": 16px, "lg": 20px, "xl": 24px),
"second-item-triple": ("sm": 12px, "md": 20px, "lg": 24px, "xl": 32px),
"second-item-quadruple": ("sm": 12px, "md": 20px, "lg": 28px, "xl": 32px),
"third-item-triple": ("sm": 10px, "md": 16px, "lg": 20px, "xl": 24px),
"third-item-quadruple": ("sm": 10px, "md": 16px, "lg": 24px, "xl": 24px),
"fourth-item": ("sm": 8px, "md": 12px, "lg": 16px, "xl": 16px)
);

$positions: (
"second-item-double": (
"sm": ("top": null, "bottom": 5px, "right": 4px, "left": null),
"md": ("top": null, "bottom": 10px, "right": 8px, "left": null),
"lg": ("top": 46px, "bottom": null, "right": 12px, "left": null),
"xl": ("top": 58px, "bottom": null, "right": 14px, "left": null)
),
"second-item-triple": (
"sm": ("top": 12px, "bottom": null, "right": 2px, "left": null),
"md": ("top": 24px, "bottom": null, "right": 5px, "left": null),
"lg": ("top": 32px, "bottom": null, "right": 9px, "left": null),
"xl": ("top": 41px, "bottom": null, "right": 11px, "left": null)
),
"second-item-quadruple": (
"sm": ("top": null, "bottom": 9px, "right": 4px, "left": null),
"md": ("top": 24px, "bottom": null, "right": 5px, "left": null),
"lg": ("top": 31px, "bottom": null, "right": 6px, "left": null),
"xl": ("top": 43px, "bottom": null, "right": 9px, "left": null)
),
"third-item-triple": (
"sm": ("top": null, "bottom": 3px, "right": null, "left": 11px),
"md": ("top": null, "bottom": 6px, "right": null, "left": 16px),
"lg": ("top": null, "bottom": 10px, "right": null, "left": 23px),
"xl": ("top": null, "bottom": 13px, "right": null, "left": 27px)
),
"third-item-quadruple": (
"sm": ("top": null, "bottom": 3px, "right": null, "left": 9px),
"md": ("top": null, "bottom": 5px, "right": null, "left": 15px),
"lg": ("top": null, "bottom": 7px, "right": null, "left": 20px),
"xl": ("top": null, "bottom": 11px, "right": null, "left": 27px)
),
"fourth-item": (
"sm": ("top": 5px, "bottom": null, "right": 6px, "left": null),
"md": ("top": 7px, "bottom": null, "right": 12px, "left": null),
"lg": ("top": 9px, "bottom": null, "right": 16px, "left": null),
"xl": ("top": 16px, "bottom": null, "right": 24px, "left": null)
),
"first-item-double": (
"sm": ("top": 4px, "bottom": null, "right": null, "left": 3px),
"md": ("top": 6px, "bottom": null, "right": null, "left": 8px),
"lg": ("top": 8px, "bottom": null, "right": null, "left": 8px),
"xl": ("top": 10px, "bottom": null, "right": null, "left": 10px)
),
"first-item-triple": (
"sm": ("top": 4px, "bottom": null, "right": null, "left": 4px),
"md": ("top": 7px, "bottom": null, "right": null, "left": 7px),
"lg": ("top": 10px, "bottom": null, "right": null, "left": 10px),
"xl": ("top": 12px, "bottom": null, "right": null, "left": 12px)
),
"first-item-quadruple": (
"sm": ("top": 5px, "bottom": null, "right": null, "left": 3px),
"md": ("top": 7px, "bottom": null, "right": null, "left": 5px),
"lg": ("top": 9px, "bottom": null, "right": null, "left": 7px),
"xl": ("top": 16px, "bottom": null, "right": null, "left": 10px)
)
);

@mixin avatar-size($size) {
height: $size;
width: $size;
Expand All @@ -27,8 +97,8 @@
$stacked_size: 18px;
$max_to_display: 1, 2;
display: inline-flex;
width: $container_size;
height: $container_size;
width: 28px;
height: 28px;
flex-basis: $container_size;
position: relative;
flex-shrink: 0;
Expand All @@ -48,7 +118,7 @@
}
}
&[class*=_single] .pb_multiple_users_stacked_item {
@include avatar-size($container_size);
@include avatar-size(28px);
}
[class^=pb_avatar_kit].second_item, [class^=pb_badge_kit].second_item {
@include position((bottom: 0, right: 0));
Expand All @@ -71,72 +141,106 @@
color: transparent;
}

&[class*=_bubble] {
@include avatar-size($bubble_container_size);
background-color: $bg_light;
border-radius: 50%;

&.dark {
background-color: $card_dark;
}

[class^=pb_avatar_kit].pb_multiple_users_stacked_item {
&.dark {
.avatar_wrapper {
border: $border_size solid $border_dark;
}
}
}

[class^=pb_avatar_kit] {
&.first_item {
@include position((top: 4px, left: 3px));
@include avatar-size(20px);

&.triple_bubble {
@include position((top: 4px, left: 4px));
@include avatar-size(16px);
// Iterate over each size to adjust the bubble container only when class contains "_bubble_"
@each $size_name, $size_value in $avatar-sizes {
&[class*=_bubble_][class*=_size_#{$size_name}] {
// Set bubble container size based on the class
$bubble_container_size: $size_value;
$container_size: $size_value;

// Apply the bubble container size
@include avatar-size($bubble_container_size);
width: $bubble_container_size;
height: $bubble_container_size;
flex-basis: $bubble_container_size;

background-color: $bg_light;
border-radius: 50%;

&.dark {
background-color: $card_dark;
}

&.quadruple_bubble {
@include position((top: 5px, left: 3px));
@include avatar-size(16px);
}
}

&.second_item {
@include position((bottom: 5px, right: 4px));
@include avatar-size(12px);

&.triple_bubble {
@include position((top: 13px, right: 2px));
[class^=pb_avatar_kit].pb_multiple_users_stacked_item {
@include avatar-size($bubble_container_size * 0.45); // Adjust the size of stacked avatars

&.dark {
.avatar_wrapper {
border: $border_size solid $border_dark;
}
}

.avatar_wrapper {
border: $border_size solid $white;
}
}

&.quadruple_bubble {
@include position((bottom: 9px, right: 4px));

[class^=pb_avatar_kit] {
// First Item
&.first_item {
@include position(map-get(map-get($positions, 'first-item-double'), $size_name));
@include avatar-size(map-get(map-get($sizes, 'first-item-double'), $size_name));

&.double_bubble {
@include position(map-get(map-get($positions, 'first-item-double'), $size_name));
@include avatar-size(map-get(map-get($sizes, 'first-item-double'), $size_name));
}

&.triple_bubble {
@include position(map-get(map-get($positions, 'first-item-triple'), $size_name));
@include avatar-size(map-get(map-get($sizes, 'first-item-triple'), $size_name));
}

&.quadruple_bubble {
@include position(map-get(map-get($positions, 'first-item-quadruple'), $size_name));
@include avatar-size(map-get(map-get($sizes, 'first-item-quadruple'), $size_name));
}
}

// Second Item
&.second_item {
@include position(map-get(map-get($positions, 'second-item-double'), $size_name));

&.double_bubble {
@include position(map-get(map-get($positions, 'second-item-double'), $size_name));
@include avatar-size(map-get(map-get($sizes, 'second-item-double'), $size_name));
}

&.triple_bubble {
@include position(map-get(map-get($positions, 'second-item-triple'), $size_name));
@include avatar-size(map-get(map-get($sizes, 'second-item-triple'), $size_name));
}

&.quadruple_bubble {
@include position(map-get(map-get($positions, 'second-item-quadruple'), $size_name));
@include avatar-size(map-get(map-get($sizes, 'second-item-quadruple'), $size_name));
}
}

// Third Item
&.third_item {
@include position(map-get(map-get($positions, 'third-item-triple'), $size_name));
@include avatar-size(map-get(map-get($sizes, 'third-item-triple'), $size_name));

&.quadruple_bubble {
@include position(map-get(map-get($positions, 'third-item-quadruple'), $size_name));
@include avatar-size(map-get(map-get($sizes, 'third-item-quadruple'), $size_name));
}
}

// Fourth Item
&.fourth_item {
@include position(map-get(map-get($positions, 'fourth-item'), $size_name));
@include avatar-size(map-get(map-get($sizes, 'fourth-item'), $size_name));
}
}
}

&.third_item {
@include position((bottom: 3px, left: 11px));
@include avatar-size(10px);

&.quadruple_bubble {
@include position((bottom: 3px, left: 9px));

&[class*=_single_bubble] {
[class^=pb_avatar_kit].first_item {
@include position((top: 0, left: 0));
@include avatar-size($bubble_container_size);
}
}
}

&.fourth_item {
@include position((top: 5px, right: 6px));
@include avatar-size(8px);
}
}
}

&[class*=_single_bubble] {
[class^=pb_avatar_kit].first_item {
@include position((top: 0, left: 0));
@include avatar-size($bubble_container_size);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ const MultipleUsersStackedSingleBubble = () => {
test('should have a single bubble', () => {
render(<MultipleUsersStackedSingleBubble />)
const kit = screen.getByTestId(testId)
expect(kit).toHaveClass("pb_multiple_users_stacked_kit_single_bubble")
expect(kit).toHaveClass("pb_multiple_users_stacked_kit_single_bubble_size_sm")

const firstItem = kit.querySelector('.first_item');
expect(firstItem).toBeInTheDocument();
Expand Down Expand Up @@ -113,7 +113,7 @@ const MultipleUsersStackedDoubleBubble = () => {
test('should have a double bubble', () => {
render(<MultipleUsersStackedDoubleBubble />)
const kit = screen.getByTestId(testId)
expect(kit).toHaveClass("pb_multiple_users_stacked_kit_bubble")
expect(kit).toHaveClass("pb_multiple_users_stacked_kit_bubble_size_sm")

const firstItem = kit.querySelector('.first_item');
expect(firstItem).toBeInTheDocument();
Expand Down Expand Up @@ -153,7 +153,7 @@ const MultipleUsersStackedTripleBubble = () => {
test('should have a triple bubble', () => {
render(<MultipleUsersStackedTripleBubble />)
const kit = screen.getByTestId(testId)
expect(kit).toHaveClass("pb_multiple_users_stacked_kit_bubble")
expect(kit).toHaveClass("pb_multiple_users_stacked_kit_bubble_size_sm")

const firstItem = kit.querySelector('.first_item');
expect(firstItem).toBeInTheDocument();
Expand Down Expand Up @@ -208,7 +208,7 @@ const MultipleUsersStackedQuadrupleBubble = () => {
test('should have a quadruple bubble', () => {
render(<MultipleUsersStackedQuadrupleBubble />)
const kit = screen.getByTestId(testId)
expect(kit).toHaveClass("pb_multiple_users_stacked_kit_bubble")
expect(kit).toHaveClass("pb_multiple_users_stacked_kit_bubble_size_sm")

const firstItem = kit.querySelector('.first_item');
expect(firstItem).toBeInTheDocument();
Expand All @@ -224,4 +224,4 @@ test('should have a quadruple bubble', () => {

const fourthItem = kit.querySelector('.fourth_item');
expect(fourthItem).toBeInTheDocument();
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ type MultipleUsersStackedProps = {
data?: { [key: string]: string },
htmlOptions?: {[key: string]: string | number | boolean | (() => void)},
id?: string,
size?: "md" | "lg" | "sm" | "xl"
users: Array<{ [key: string]: string }>,
variant: "default" | "bubble",
}
Expand All @@ -27,14 +28,17 @@ const MultipleUsersStacked = (props: MultipleUsersStackedProps) => {
htmlOptions = {},
id,
users,
size = "sm",
variant = "default",
} = props

const moreThanTwo = users.length > 2
const onlyOne = users.length == 1
const isBubble = variant === "bubble"
const doubleBubble = isBubble && users.length === 2
const tripleBubble = isBubble && users.length === 3
const quadrupleBubble = isBubble && users.length > 3
const sizeClass = isBubble ? `size_${size}` : ""
const displayCount = () => {
return moreThanTwo ? 1 : users.length
}
Expand All @@ -43,17 +47,19 @@ const MultipleUsersStacked = (props: MultipleUsersStackedProps) => {
const htmlProps = buildHtmlProps(htmlOptions)
const classes = classnames(buildCss(
'pb_multiple_users_stacked_kit',
{ single: onlyOne, bubble: isBubble }), globalProps(props), className)
{ single: onlyOne, bubble: isBubble }, sizeClass),
globalProps(props),
className)

const firstUser = () => {
return users.slice(0, 1).map((userObject, index) => {
return (
<Avatar
{...userObject}
className={`pb_multiple_users_stacked_item first_item${tripleBubble ? " triple_bubble" : ""}${quadrupleBubble ? " quadruple_bubble" : ""}`}
className={`pb_multiple_users_stacked_item first_item ${doubleBubble ? "double_bubble" : ""}${tripleBubble ? " triple_bubble" : ""}${quadrupleBubble ? " quadruple_bubble" : ""}`}
dark={dark}
key={index}
size={isBubble ? "sm" : "xs"}
size={isBubble ? "md" : "xs"}
/>
)
})
Expand All @@ -65,10 +71,10 @@ const MultipleUsersStacked = (props: MultipleUsersStackedProps) => {
return (
<Avatar
{...userObject}
className={`pb_multiple_users_stacked_item second_item${tripleBubble ? " triple_bubble" : ""}${quadrupleBubble ? " quadruple_bubble" : ""}`}
className={`pb_multiple_users_stacked_item second_item ${doubleBubble ? "double_bubble" : ""}${tripleBubble ? " triple_bubble" : ""}${quadrupleBubble ? " quadruple_bubble" : ""}`}
dark={dark}
key={index}
size="xs"
size={isBubble ? "md" : "xs"}
/>
)
})
Expand All @@ -81,10 +87,10 @@ const MultipleUsersStacked = (props: MultipleUsersStackedProps) => {
return (
<Avatar
{...userObject}
className={`pb_multiple_users_stacked_item third_item${quadrupleBubble ? " quadruple_bubble" : ""}`}
className={`pb_multiple_users_stacked_item third_item ${doubleBubble ? "double_bubble" : ""}${tripleBubble ? " triple_bubble" : ""}${quadrupleBubble ? " quadruple_bubble" : ""}`}
dark={dark}
key={index}
size="xs"
size="md"
/>
)
})
Expand All @@ -97,10 +103,10 @@ const MultipleUsersStacked = (props: MultipleUsersStackedProps) => {
return (
<Avatar
{...userObject}
className="pb_multiple_users_stacked_item fourth_item"
className="pb_multiple_users_stacked_item fourth_item quadruple_bubble"
dark={dark}
key={index}
size="xs"
size="md"
/>
)
})
Expand Down
Loading

0 comments on commit 580161f

Please sign in to comment.