import { forwardRef, useState, useEffect, useCallback } from 'react' import { Avatar } from '../Avatar' import { AvatarShape, AvatarSize } from '../Avatar/types' import type { AvatarGroupProps } from './types' import { StyledAvatarGroupContainer, StyledAvatarWrapper, StyledOverflowCounter, VisuallyHidden, } from './StyledAvatarGroup' import { createMenuItems } from './avatarGroupUtils' import Menu from '../Menu/Menu' import { Skeleton } from '../Skeleton' import { useResponsiveTokens } from '../../hooks/useResponsiveTokens' import { AvatarTokensType } from '../Avatar/avatar.tokens' const AvatarGroup = forwardRef( ( { avatars = [], maxCount = 5, size = AvatarSize.MD, shape = AvatarShape.CIRCULAR, selectedAvatarIds, onSelectionChange, skeleton, ...props }, ref ) => { const tokens = useResponsiveTokens('AVATAR') const safeMaxCount = Math.max(1, maxCount) const [internalSelectedIds, setInternalSelectedIds] = useState< (string | number)[] >(selectedAvatarIds || []) const visibleAvatars = avatars.slice(0, safeMaxCount) const overflowAvatars = avatars.slice(safeMaxCount) const overflowCount = overflowAvatars.length useEffect(() => { setInternalSelectedIds(selectedAvatarIds || []) }, [selectedAvatarIds]) const handleSelect = useCallback( (id: string | number) => { setInternalSelectedIds((prevSelected) => { const newSelectedIds = prevSelected.includes(id) ? prevSelected.filter((selectedId) => selectedId !== id) : [...prevSelected, id] onSelectionChange?.(newSelectedIds) return newSelectedIds }) }, [onSelectionChange] ) const menuItems = createMenuItems( overflowAvatars, internalSelectedIds, handleSelect, Avatar ) return ( 0 ? `, ${internalSelectedIds.length} selected` : ''}`} aria-live="polite" aria-atomic="true" data-avatar-group="avatar-group" data-avatar-group-count={avatars.length} data-avatar-group-selected-count={internalSelectedIds.length} data-avatar-group-max-count={safeMaxCount} {...props} > {visibleAvatars.map((avatar, index) => { const isSelected = internalSelectedIds.includes(avatar.id) const avatarName = avatar.alt || (typeof avatar.fallback === 'string' ? avatar.fallback : `Avatar ${avatar.id}`) const descriptionId = `avatar-group-item-${avatar.id}-description` return ( handleSelect(avatar.id)} onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault() handleSelect(avatar.id) } }} > {`Avatar ${index + 1} of ${visibleAvatars.length}${overflowCount > 0 ? `, ${overflowCount} more available` : ''}`} ) })} {overflowCount > 0 && (skeleton?.show ? ( ) : (