Skip to content

Commit

Permalink
feat(avatarGroup): update avatar group popover list design
Browse files Browse the repository at this point in the history
  • Loading branch information
anuradha9712 committed Sep 24, 2024
1 parent 7975d7e commit 2de75c4
Show file tree
Hide file tree
Showing 11 changed files with 267 additions and 49 deletions.
34 changes: 16 additions & 18 deletions core/components/atoms/avatarGroup/AvatarGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import AvatarCount from './AvatarCount';
import Avatars from './Avatars';
import AvatarPopperBody from './AvatarPopperBody';

interface AvatarData extends Record<string, any> {
export interface AvatarData extends Record<string, any> {
firstName?: string;
lastName?: string;
appearance?: AvatarProps['appearance'];
Expand All @@ -23,9 +23,11 @@ interface AvatarPopoverProps {
appendToBody?: PopoverProps['appendToBody'];
dark?: PopoverProps['dark'];
position?: PopoverProps['position'];
on?: PopoverProps['on'];
maxHeight?: number;
popperClassName?: string;
on?: PopoverProps['on'];
maxHeight?: number | string;
minHeight?: number | string;
width?: number | string;
}

export interface AvatarGroupProps extends BaseProps {
Expand Down Expand Up @@ -65,10 +67,11 @@ export interface AvatarGroupProps extends BaseProps {
* AvatarPopoverProps: {
* popperRenderer?: (names: AvatarData[]) => JSX.Element;
* appendToBody?: boolean;
* dark?: boolean;
* position?: Position;
* on?: ActionType;
* maxHeight?: number;
* minHeight?: number | string;
* width?: number | string;
* popperClassName?: string;
* }
* </pre>
Expand All @@ -77,10 +80,11 @@ export interface AvatarGroupProps extends BaseProps {
* | --- | --- | --- |
* | popperRenderer | Callback function to create custom popover content | |
* | appendToBody | Appends `Popover` wrapper inside body | true |
* | dark | Changes background of `Popover` | true |
* | position | Position to place `Popover` | bottom |
* | on | Event triggering the `Popover` | hover |
* | maxHeight | Max height of `Popover Text Wrapper` (does not work in case of custom popperRenderer) | 150 |
* | maxHeight | Max height of `Popover Text Wrapper` (does not work in case of custom popperRenderer) | 256 |
* | minHeight | Min height of `Popover Text Wrapper` (does not work in case of custom popperRenderer) | |
* | width | width of `Popover Text Wrapper` (does not work in case of custom popperRenderer) | 176 |
* | popperClassName | Custom className added to `Popover` | |
*
*/
Expand All @@ -96,10 +100,11 @@ export const AvatarGroup = (props: AvatarGroupProps) => {

const {
popperRenderer,
maxHeight = 150,
maxHeight = 256,
width = 176,
minHeight,
position = 'bottom',
on = 'hover',
dark = true,
appendToBody = true,
popperClassName = '',
} = popoverOptions;
Expand Down Expand Up @@ -128,31 +133,24 @@ export const AvatarGroup = (props: AvatarGroupProps) => {
className
);

const popperClass = classNames(
{
['AvatarGroup-Popper']: true,
},
popperClassName
);

return (
<div data-test="DesignSystem-AvatarGroup" {...baseProps} className={`${AvatarGroupClass} d-inline-flex`}>
<Avatars size={size} avatarList={avatarList} avatarStyle={avatarStyle} tooltipPosition={tooltipPosition} />
{list.length - max > 0 && list.length !== 3 && (
<Popover
on={on}
dark={dark}
trigger={<AvatarCount on={on} size={size} hiddenAvatarCount={hiddenAvatarCount} avatarStyle={avatarStyle} />}
position={position}
appendToBody={appendToBody}
className={popperClass}
offset="medium"
>
<AvatarPopperBody
hiddenAvatarList={list.slice(max, list.length)}
popperRenderer={popperRenderer}
maxHeight={maxHeight}
dark={dark}
minHeight={minHeight}
width={width}
popperClassName={popperClassName}
/>
</Popover>
)}
Expand Down
64 changes: 45 additions & 19 deletions core/components/atoms/avatarGroup/AvatarPopperBody.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,61 @@
import * as React from 'react';
import { Text } from '@/index';
import { Text, Listbox, Tooltip } from '@/index';
import classNames from 'classnames';
import { AvatarData } from './AvatarGroup';

const AvatarPopperBody = (props: any) => {
const { hiddenAvatarList, popperRenderer, maxHeight, dark } = props;
interface AvatarPopperProps {
popperRenderer?: (names: AvatarData[]) => JSX.Element;
maxHeight?: number | string;
minHeight?: number | string;
width?: number | string;
popperClassName?: string;
hiddenAvatarList: AvatarData[];
}

const AvatarPopperBody = (props: AvatarPopperProps) => {
const { hiddenAvatarList, popperRenderer, maxHeight, minHeight, width, popperClassName } = props;

if (popperRenderer) {
return popperRenderer(hiddenAvatarList);
}

const popperClass = classNames(
{
['AvatarGroup-Popper py-3']: true,
},
popperClassName
);

return (
<div className="px-4 py-3">
<div className="AvatarGroup-TextWrapper" style={{ maxHeight }}>
{hiddenAvatarList.map((item: any, ind: any) => {
const { firstName = '', lastName = '', tooltipSuffix = '' } = item;
<div style={{ width, minHeight, maxHeight }} className={popperClass} data-test="DesignSystem-AvatarGroup--Popover">
<Listbox
showDivider={false}
type="description"
size="compressed"
tagName="ul"
data-test="DesignSystem-AvatarGroup--List"
>
{hiddenAvatarList.map((item: AvatarData, index: number) => {
const { firstName = '', lastName = '', tooltipSuffix = '', disabled } = item;
const name = `${firstName} ${lastName} ${tooltipSuffix}`;
const AvatarTextClass = classNames({
[`mb-4`]: ind < hiddenAvatarList.length - 1,
});
const elementRef = React.useRef(null);

return (
<Text
key={ind}
appearance={dark ? 'white' : 'default'}
className={AvatarTextClass}
data-test="DesignSystem-AvatarGroup--Text"
>
{name}
</Text>
<Tooltip key={index} showOnTruncation={true} tooltip={name} elementRef={elementRef}>
<Listbox.Item
disabled={disabled}
className="cursor-default"
tagName="li"
data-test="DesignSystem-AvatarGroup--Item"
>
<Text ref={elementRef} data-test="DesignSystem-AvatarGroup--Text" className="ellipsis--noWrap">
{name}
</Text>
</Listbox.Item>
</Tooltip>
);
})}
</div>
</Listbox>
</div>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import * as React from 'react';
import { AvatarGroup, Text } from '@/index';
import { list } from './AvatarList';

export const OverflowBehavior = () => {
return (
<div className="d-flex">
<div className="flex-column mr-9 ">
<Text weight="strong">Dynamic Width</Text>
<div className="mt-4">
<AvatarGroup list={list} popoverOptions={{ width: 200 }} />
</div>
</div>
<div className="flex-column">
<Text weight="strong">Truncate</Text>
<div className="mt-4">
<AvatarGroup list={list} />
</div>
</div>
</div>
);
};

const customCode = `() => {
const list = [
{
firstName: 'John',
lastName: 'Doe',
},
{
firstName: 'Steven',
lastName: 'Packton',
},
{
firstName: 'Nancy',
lastName: 'Wheeler'
},
{
firstName: 'Monica',
lastName: 'Geller'
},
{
firstName: 'Arya',
lastName: 'Stark',
},
{
firstName: 'Rachel',
lastName: 'Green',
},
{
firstName: 'Walter Paxton',
lastName: 'Wheeler'
},
];
return (
<div className="d-flex">
<div className="flex-column mr-9 ">
<Text weight="strong">Dynamic Width</Text>
<div className="mt-4">
<AvatarGroup list={list} popoverOptions={{ width: 200 }} />
</div>
</div>
<div className="flex-column">
<Text weight="strong">Truncate</Text>
<div className="mt-4">
<AvatarGroup list={list} />
</div>
</div>
</div>
);
}`;

export default {
title: 'Components/Avatar/AvatarGroup/Overflow Behavior',
component: AvatarGroup,
parameters: {
docs: {
docPage: {
customCode,
},
},
},
};
6 changes: 2 additions & 4 deletions core/components/atoms/avatarGroup/__stories__/index.story.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,14 @@ import { AvatarGroup } from '@/index';
import { list } from './AvatarList';

export const all = () => {
const position = 'bottom-end';
const position = 'bottom';
const on = 'hover';
const dark = true;
const max = 2;
const options = {
max,
popoverOptions: {
on,
position,
dark,
},
list: list.slice(0, 4),
};
Expand Down Expand Up @@ -51,7 +49,7 @@ const customCode = `() => {
lastName: 'Wheeler'
},
];
return <AvatarGroup list={list} popoverOptions={{ dark: true, on: 'hover', position: 'bottom'}}/>;
return <AvatarGroup list={list} popoverOptions={{ position: 'bottom'}} />;
}`;

export default {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { AvatarGroup, Avatar, Text } from '@/index';
import { list } from '../AvatarList';
import './style.css';

export const customPopper = () => {
export const customPopover = () => {
const popperRenderer = (names) => {
const AvatarList = names.map((avatar, index) => {
const { firstName, lastName, appearance } = avatar;
Expand All @@ -25,7 +25,7 @@ export const customPopper = () => {
return <div className="overflow-auto py-4 px-6 UserAvatars-popover">{AvatarList}</div>;
};

return <AvatarGroup list={list} popoverOptions={{ popperRenderer, dark: false, on: 'click' }} />;
return <AvatarGroup list={list} popoverOptions={{ popperRenderer, dark: false }} />;
};

const customCode = `/*
Expand Down Expand Up @@ -95,13 +95,13 @@ const customCode = `/*
return (
<AvatarGroup
list={list}
popoverOptions={{ dark: false, on: 'click', popperRenderer }}
popoverOptions={{ dark: false, popperRenderer }}
/>
);
}`;

export default {
title: 'Components/Avatar/AvatarGroup/Variants/Custom Popper',
title: 'Components/Avatar/AvatarGroup/Variants/Custom Popover',
component: AvatarGroup,
parameters: {
docs: {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import * as React from 'react';
import { AvatarGroup, Text } from '@/index';
import { list } from '../AvatarList';

export const Trigger = () => {
return (
<div className="d-flex">
<div className="flex-column mr-9 ">
<Text weight="strong">Hover</Text>
<div className="mt-4">
<AvatarGroup size="regular" list={list.slice(0, 4)} popoverOptions={{ on: 'hover' }} />
</div>
</div>
<div className="flex-column">
<Text weight="strong">Click</Text>
<div className="mt-4">
<AvatarGroup list={list.slice(0, 4)} popoverOptions={{ on: 'click' }} />
</div>
</div>
</div>
);
};

const customCode = `() => {
const list = [
{
firstName: 'John',
lastName: 'Doe',
},
{
firstName: 'Steven',
lastName: 'Packton',
},
{
firstName: 'Nancy',
lastName: 'Wheeler'
},
{
firstName: 'Monica',
lastName: 'Geller'
},
];
return (
<div className="d-flex">
<div className="flex-column mr-9 ">
<Text weight="strong">Hover</Text>
<div className="mt-4">
<AvatarGroup list={list.slice(0, 4)} popoverOptions={{ on: 'hover' }} />
</div>
</div>
<div className="flex-column">
<Text weight="strong">Click</Text>
<div className="mt-4">
<AvatarGroup list={list.slice(0, 4)} popoverOptions={{ on: 'click' }} />
</div>
</div>
</div>
);
}`;

export default {
title: 'Components/Avatar/AvatarGroup/Variants/Trigger',
component: AvatarGroup,
parameters: {
docs: {
docPage: {
customCode,
},
},
},
};
Loading

0 comments on commit 2de75c4

Please sign in to comment.