AvatarGroup
Props
Usage guidelines
- For the general display of groups of people, companies and/or brands.
- In cases where an affordance for adding collaborators is needed.
Best Practices
Use the default alternative if no image source is available. This should be the first character of the provided name.
Use alternative graphics or icons
Use AvatarGroup to represent a group of people and/or organizations.
Use AvatarGroup to represent metaphorical ideas, like multiple Boards or trends. Instead, consider an Image or the appropriate interactive component.
Accessibility
ARIA attributes
AvatarGroup requires accessibilityLabel
. AvatarGroup is a group of elements that require a parent label describing both the data presented and the call to action in the case of button and link roles. As seen in the example below, the screen-reader reads: "Collaborators: Keerthi, Alberto, and 10 more. Add collaborators to this board."
If AvatarGroup is used as a control button to show/hide Popover-component, we recommend passing the following ARIA attributes to assist screen readers:
accessibilityControls
: informs the screen reader that AvatarGroup controls the display of an anchored Popover-component. It populates aria-controls.accessibilityHaspopup
: informs the screen reader that there’s a Popover-component attached to AvatarGroup. It populates aria-haspopup.accessibilityExpanded
: informs the screen reader whether an anchored Popover-component is currently open or closed. It populates aria-expanded.
import { useState, useRef, useEffect } from 'react'; import { Flex, AvatarGroup, Text, SearchField, Layer, Popover, Box, } from 'gestalt'; function SearchCollaboratorsField() { const ref = useRef(); useEffect(() => { ref.current?.focus(); }, []); return ( <SearchField accessibilityLabel="Search other users" id="searchField" onChange={() => {}} placeholder="Search by name or email" size="lg" ref={ref} /> ); } export default function Example() { const [open, setOpen] = useState(false); const anchorRef = useRef(); return ( <Flex height="100%" width="100%"> <Box height="200" marginTop={6} padding={2}> <AvatarGroup accessibilityLabel="Collaborators: Keerthi, Alberto, and 10 more. Add collaborators to this board." accessibilityExpanded={open} addCollaborators role="button" onClick={() => setOpen((value) => !value)} ref={anchorRef} size="md" collaborators={[ { name: 'Keerthi', src: 'https://i.ibb.co/ZfCZrY8/keerthi.jpg', }, { name: 'Alberto', src: 'https://i.ibb.co/NsK2w5y/Alberto.jpg', }, ...new Array(10), ]} /> </Box> {open && ( <Layer> <Popover anchor={anchorRef.current} idealDirection="down" onDismiss={() => setOpen(false)} positionRelativeToAnchor={false} size="xl" > <Box flex="grow" marginEnd={4} marginStart={4} marginTop={6} marginBottom={8} width={360} > <Flex direction="column" gap={{ column: 6, row: 0 }}> <Text align="center" color="default" weight="bold"> Invite collaborators </Text> <SearchCollaboratorsField /> </Flex> </Box> </Popover> </Layer> )} </Flex> ); }
Keyboard Interaction
If AvatarGroup is acting as a button or link, the Tab key will focus the AvatarGroup.
Hitting the Enter or Return key opens a dialog or redirects to a new page (depending on the role) and the user can then add or view collaborators.
Localization
Be sure to localize accessibilityLabel
.
Variants
Fixed sizes
AvatarGroup is available in 3 fixed height sizes: xs
(24px), sm
(32px), and md
(48px).
Responsive sizing
AvatarGroup is a responsive component. Avatar Groups that are not given a size prop or use size fit
will expand to fit to the width of their parent container. A common use case is to achieve column-based sizing. Resize the width or number of avatars to see the AvatarGroup change to match the width of the Column it's been placed in.
import { Flex, AvatarGroup, Box, Text, Link } from 'gestalt'; export default function Example() { return ( <Flex height="100%" width="100%" alignItems="center" justifyContent="center" > <Box width={600} height={100} padding={2}> <Flex alignItems="center" height="100%"> <Box column={5} height="100%"> <AvatarGroup accessibilityLabel="Collaborators: Keerthi, Alberto, and Shanice." size="fit" collaborators={[ { name: 'Keerthi', src: 'https://i.ibb.co/ZfCZrY8/keerthi.jpg', }, { name: 'Alberto', src: 'https://i.ibb.co/NsK2w5y/Alberto.jpg', }, { name: 'Shanice', src: 'https://i.ibb.co/7tGKGvb/shanice.jpg', }, ]} /> </Box> <Box column={7} marginStart={2}> <Text inline>The </Text> <Text inline weight="bold"> <Link inline href="https://www.pinterest.com/search/boards/?q=quick%20vegan%20recipes&rs=typed&term_meta[]=quick%7Ctyped&term_meta[]=vegan%7Ctyped&term_meta[]=recipes%7Ctyped" > Quick Vegan Recipes{' '} </Link> </Text> <Text inline> board has 3 followers.</Text> </Box> </Flex> </Box> </Flex> ); }
Collaborators display
AvatarGroup displays up to three user avatars. More users, if present, will be displayed as a numerical count for the md
and fit
sizes.
Role
AvatarGroup can be display only, but can also act as a button or link. It will only be clickable if role is set to button
or link
. For button role, onClick
is required. For link role, href
is required.
import { useState, useRef } from 'react'; import { Flex, AvatarGroup, Avatar, Text, Box, Layer, Popover } from 'gestalt'; const collaborators = [ { name: 'Keerthi', src: 'https://i.ibb.co/ZfCZrY8/keerthi.jpg', }, { name: 'Alberto', src: 'https://i.ibb.co/NsK2w5y/Alberto.jpg', }, { name: 'Shanice', src: 'https://i.ibb.co/7tGKGvb/shanice.jpg', }, ]; function List() { return ( <Flex direction="column" gap={{ column: 2, row: 0 }}> {collaborators.map(({ name, src }) => ( <Flex key={name} alignItems="center" gap={{ row: 2, column: 0 }}> <Avatar size="md" name={name} src={src} /> <Text weight="bold">{name}</Text> </Flex> ))} </Flex> ); } export default function Example() { const [open, setOpen] = useState(false); const anchorRef = useRef(); return ( <Flex height="100%" width="100%" alignItems="center" justifyContent="center" > <AvatarGroup accessibilityLabel="Click to see group collaborators." role="button" onClick={() => setOpen((value) => !value)} ref={anchorRef} size="md" collaborators={collaborators} /> {open && ( <Layer> <Popover anchor={anchorRef.current} idealDirection="down" onDismiss={() => setOpen(false)} positionRelativeToAnchor={false} size="xs" > <Box flex="grow" marginEnd={4} marginStart={4} marginTop={6} marginBottom={8} width={360} > <Flex direction="column" gap={{ column: 6, row: 0 }}> <Text align="center" color="default" weight="bold"> Collaborators </Text> <List /> </Flex> </Box> </Popover> </Layer> )} </Flex> ); }
import { AvatarGroup, Flex } from 'gestalt'; export default function Example() { const collaborators = [ { name: 'Keerthi', src: 'https://i.ibb.co/ZfCZrY8/keerthi.jpg', }, { name: 'Alberto', src: 'https://i.ibb.co/NsK2w5y/Alberto.jpg', }, { name: 'Shanice', src: 'https://i.ibb.co/7tGKGvb/shanice.jpg', }, ]; return ( <Flex height="100%" width="100%" alignItems="center" justifyContent="center" > <AvatarGroup accessibilityLabel="Visit group activity board." role="link" onClick={() => {}} size="md" collaborators={collaborators} href="#Role" /> </Flex> ); }
Component quality checklist
Quality item | Status | Status description |
---|---|---|
Figma Library | Ready | Component is available in Figma across all platforms. |
Responsive Web | Ready | Component is available in code for web and mobile web. |
iOS | Component is not currently available in code for iOS. | |
Android | Component is not currently available in code for Android. |
Related
Avatar
Avatar is the ideal component in cases where only one person or brand needs to be displayed.