Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(AvatarGroup): add disabled state #2126

Merged
merged 7 commits into from
May 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import minus from "./minus.svg";
import person1 from "./person1.png";
import person2 from "./person2.png";
import person3 from "./person3.png";
import person4 from "./person4.png";
import maleIcon from "./maleIcon.png";
import femaleIcon from "./femaleIcon.png";
import owner from "./owner.svg";

export { home, guest, minus, person1, person2, person3, maleIcon, femaleIcon, owner };
export { home, guest, minus, person1, person2, person3, person4, maleIcon, femaleIcon, owner };
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,16 @@ export const Overview = {
size: Avatar.sizes.LARGE,
src: window.location.origin + "/" + person1,
type: Avatar.types.IMG,
ariaLabel: "Hadas Fahri"
ariaLabel: "Julia Martinez"
}
};

export const Size = {
render: () => (
<>
<Avatar size={Avatar.sizes.SMALL} src={person1} type={Avatar.types.IMG} ariaLabel="Hadas Fahri" />
<Avatar size={Avatar.sizes.MEDIUM} src={person1} type={Avatar.types.IMG} ariaLabel="Hadas Fahri" />
<Avatar size={Avatar.sizes.LARGE} src={person1} type={Avatar.types.IMG} ariaLabel="Hadas Fahri" />
<Avatar size={Avatar.sizes.SMALL} src={person1} type={Avatar.types.IMG} ariaLabel="Julia Martinez" />
<Avatar size={Avatar.sizes.MEDIUM} src={person1} type={Avatar.types.IMG} ariaLabel="Julia Martinez" />
<Avatar size={Avatar.sizes.LARGE} src={person1} type={Avatar.types.IMG} ariaLabel="Julia Martinez" />
</>
),

Expand Down Expand Up @@ -130,14 +130,14 @@ export const AvatarWithRightBadge = {
type={Avatar.types.IMG}
src={person1}
bottomRightBadgeProps={{ src: guest }}
ariaLabel="Hadas Fahri"
ariaLabel="Julia Martinez"
/>
<Avatar
size={Avatar.sizes.LARGE}
type={Avatar.types.IMG}
src={person1}
bottomRightBadgeProps={{ src: owner }}
ariaLabel="Hadas Fahri"
ariaLabel="Julia Martinez"
/>
</>
),
Expand All @@ -154,14 +154,14 @@ export const AvatarWithLeftBadge = {
type={Avatar.types.IMG}
src={person1}
bottomLeftBadgeProps={{ src: home }}
ariaLabel="Hadas Fahri"
ariaLabel="Julia Martinez"
/>
<Avatar
size={Avatar.sizes.LARGE}
type={Avatar.types.IMG}
src={person1}
bottomLeftBadgeProps={{ src: minus }}
ariaLabel="Hadas Fahri"
ariaLabel="Julia Martinez"
/>
</>
),
Expand All @@ -173,17 +173,17 @@ export const AvatarWithTooltip = {
render: () => (
<Flex direction={Flex.directions.ROW} gap={Flex.gaps.LARGE} align={Flex.align.START}>
<StoryDescription description="Aria label tooltip" vertical align={StoryDescription.align.START}>
<Avatar size={Avatar.sizes.LARGE} type={Avatar.types.IMG} src={person1} ariaLabel={"Hadas Fahri"} />
<Avatar size={Avatar.sizes.LARGE} type={Avatar.types.IMG} src={person1} ariaLabel={"Julia Martinez"} />
</StoryDescription>
<StoryDescription description="Text tooltip" vertical align={StoryDescription.align.START}>
<Avatar
size={Avatar.sizes.LARGE}
type={Avatar.types.IMG}
src={person1}
tooltipProps={{
content: "Hadas Farhi"
content: "Julia Martinez"
}}
ariaLabel={"Hadas Fahri"}
ariaLabel={"Julia Martinez"}
/>
</StoryDescription>
<StoryDescription description="JSX tooltip" vertical align={StoryDescription.align.START}>
Expand All @@ -192,10 +192,10 @@ export const AvatarWithTooltip = {
type={Avatar.types.IMG}
src={person1}
tooltipProps={{
content: <b>Hadas Farhi</b>,
content: <b>Julia Martinez</b>,
position: Tooltip.positions.BOTTOM
}}
ariaLabel={"Hadas Fahri"}
ariaLabel={"Julia Martinez"}
/>
</StoryDescription>
</Flex>
Expand All @@ -218,7 +218,7 @@ export const ClickableAvatar = {
size={Avatar.sizes.LARGE}
type={Avatar.types.IMG}
src={person1}
ariaLabel="Hadas Fahri"
ariaLabel="Julia Martinez"
onClick={incrementCount}
/>
<Counter count={count} />
Expand All @@ -232,9 +232,9 @@ export const ClickableAvatar = {
export const MultipleAvatars = {
render: () => (
<AvatarGroup max={2} size={Avatar.sizes.LARGE}>
<Avatar type={Avatar.types.IMG} src={person1} ariaLabel="Hadas Fahri" />
<Avatar type={Avatar.types.IMG} src={person2} ariaLabel="Sergey Roytman" />
<Avatar type={Avatar.types.IMG} src={person3} ariaLabel="Yossi Saadi" />
<Avatar type={Avatar.types.IMG} src={person1} ariaLabel="Julia Martinez" />
<Avatar type={Avatar.types.IMG} src={person2} ariaLabel="Marco DiAngelo" />
<Avatar type={Avatar.types.IMG} src={person3} ariaLabel="Liam Caldwell" />
</AvatarGroup>
),

Expand Down
13 changes: 10 additions & 3 deletions packages/core/src/components/AvatarGroup/AvatarGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ export interface AvatarGroupProps extends VibeComponentProps {
*/
// TODO remove this prop in the next major release, should be no padding by default
removePadding?: boolean;
/**
* If true, the component will be disabled and non interactive
*/
disabled?: boolean;
}

const AvatarGroup: React.FC<AvatarGroupProps> = ({
Expand All @@ -57,7 +61,8 @@ const AvatarGroup: React.FC<AvatarGroupProps> = ({
counterProps,
counterTooltipCustomProps,
counterTooltipIsVirtualizedList = false,
removePadding = false
removePadding = false,
disabled
}) => {
const { displayAvatars, counterTooltipAvatars } = useMemo(() => {
if (!children) {
Expand All @@ -72,12 +77,13 @@ const AvatarGroup: React.FC<AvatarGroupProps> = ({
size: size || avatar?.props?.size,
type: type || avatar?.props?.type,
className: cx(styles.avatarContainer, avatarClassName),
onClick: (event: React.MouseEvent | React.KeyboardEvent) => avatarOnClick(event, avatar.props)
onClick: (event: React.MouseEvent | React.KeyboardEvent) => avatarOnClick(event, avatar.props),
disabled
});
}),
counterTooltipAvatars: childrenArray.slice(max)
};
}, [avatarClassName, children, max, size, type]);
}, [avatarClassName, children, disabled, max, size, type]);

if (!children) {
return null;
Expand All @@ -93,6 +99,7 @@ const AvatarGroup: React.FC<AvatarGroupProps> = ({
counterTooltipIsVirtualizedList={counterTooltipIsVirtualizedList}
size={size}
type={type}
disabled={disabled}
/>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@
color: var(--primary-text-color);
background-color: var(--ui-background-color);
}

.disabled,
&.disabled {
background-color: var(--disabled-background-color);
color: var(--disabled-text-color);
}
talkor marked this conversation as resolved.
Show resolved Hide resolved
}

.menu {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export interface AvatarGroupCounterProps extends VibeComponentProps {
size?: AvatarSize;
type?: AvatarType;
counterAriaLabel?: string;
disabled?: boolean;
}

const AvatarGroupCounter: React.FC<AvatarGroupCounterProps> = ({
Expand All @@ -38,7 +39,8 @@ const AvatarGroupCounter: React.FC<AvatarGroupCounterProps> = ({
counterTooltipIsVirtualizedList = false,
size = Avatar.sizes.MEDIUM,
type,
counterAriaLabel
counterAriaLabel,
disabled
}) => {
const {
color: counterColor = Counter.colors.LIGHT,
Expand All @@ -64,6 +66,7 @@ const AvatarGroupCounter: React.FC<AvatarGroupCounterProps> = ({
maxDigits={counterMaxDigits}
ariaLabel={counterAriaLabel ? counterAriaLabel : `Tab for more ${counterAriaLabelItemsName}`}
noAnimation={noAnimation}
counterClassName={cx({ [styles.disabled]: disabled })}
/>
);
}, [
Expand All @@ -73,13 +76,25 @@ const AvatarGroupCounter: React.FC<AvatarGroupCounterProps> = ({
counterMaxDigits,
counterPrefix,
counterValue,
disabled,
noAnimation
]);

if (!counterTooltipAvatars.length && !counterValue) {
return null;
}

if (disabled) {
return (
<div
ref={counterContainerRef}
className={cx(styles.counterContainer, styles.disabled, counterSizeStyle, counterColorStyle)}
>
{counterComponent()}
</div>
);
}
YossiSaadi marked this conversation as resolved.
Show resolved Hide resolved

const areAvatarsClickable = counterTooltipAvatars.some(a => a.props?.onClick);
if (areAvatarsClickable) {
return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Use this component if you need to stack avatars as a group.

### Size

As an avatar, avatar groups appear in 3 sizes: Small, Medium, and Large.
Avatar Group appears in 3 sizes: Small, Medium, and Large.

<Canvas of={AvatarGroupStories.Size} />

Expand All @@ -53,30 +53,36 @@ You can use Light or Dark counter color to maintain visual hierarchy.

<Canvas of={AvatarGroupStories.ColorVariants} />

### Custom counter
### Clickable vs. Hover

You can pass `counterProps` to specify counter params.
If avatars are clickable, they will be displayed via <StorybookLink page="Navigation/Menu/Menu">Menu</StorybookLink> and user will be able to navigate each additional item.
Otherwise, avatars will be displayed in a Tooltip with no item's navigation.

<Canvas of={AvatarGroupStories.CustomCounter} />
<Canvas of={AvatarGroupStories.HoverVsClickable} />

### Grid tooltip
### Disabled

When tooltip text for additional avatars is not passed, extra avatars will be displayed in a grid mode.
Use when the avatar group is inactive in the specific context.

<Canvas of={AvatarGroupStories.GridTooltip} />
<Canvas of={AvatarGroupStories.Disabled} />

### Max amount to display
### Max avatars shown

Choose the maximum amount of avatars you want to display.
Choose the ammount of avatars you want to show

<Canvas of={AvatarGroupStories.MaxAmountToDisplay} />
<Canvas of={AvatarGroupStories.MaxAvatarsToDisplay} />

### Hover vs Clickable
### Custom counter

If avatars are clickable, they will be displayed via <StorybookLink page="Navigation/Menu/Menu">Menu</StorybookLink> and user will be able to navigate each additional item.
Otherwise, avatars will be displayed in a Tooltip with no item's navigation.
You can pass `counterProps` to specify counter params.

<Canvas of={AvatarGroupStories.HoverVsClickable} />
<Canvas of={AvatarGroupStories.CustomCounter} />

### Grid tooltip

When tooltip text for additional avatars is not passed, extra avatars will be displayed in a grid mode.

<Canvas of={AvatarGroupStories.GridTooltip} />

### Virtualized list

Expand Down
Loading